/*
 * TCSS 422 - Spring quarter 2011
 * Team: 	Googlers
 * Members: Deepa Sahni, Krisnil Gounder, Michael Schweiger
 * Date: 	April 8, 2011
 */
package ui;

import java.util.LinkedList;
import java.util.List;

/**
 * An object designed to display data passed to it (via toString method).
 * This object is thread safe.
 * Data will be displayed in the order it arrives to this object.
 * @author Michael Schweiger
 * @version 1.0
 */
public abstract class Reporter implements Runnable {
	
	/**
	 * An internal buffer of data that needs to be displayed.
	 */
	private final List<Object> my_data_queue;
	
	/**
	 * The constructor.
	 */
	public Reporter() {
		my_data_queue = new LinkedList<Object>();
	}
	
	/**
	 * Add an object to the data queue.  This method is thread safe.  Note that objects
	 * are not copied, so adding an object and modifying externally before displaying will
	 * alter what is displayed.
	 * @param the_object The object to be displayed.
	 * @throws IllegalArgumentException if the_object is null.
	 */
	public synchronized void add(final Object the_object) throws IllegalArgumentException {
		if (the_object == null) {
			throw new IllegalArgumentException("Cannot add null objects!");
		}
		my_data_queue.add(the_object);
		notifyAll();
	}
	
	/**
	 * Starts the thread by running the abstract display method.
	 */
	public void run() {
		display();
	}
	
	/**
	 * Synchronized method for determining if the data queue is empty.
	 * @return True if it is empty, false otherwise.
	 */
	protected synchronized boolean hasMoreData() {
		return my_data_queue.isEmpty();
	}
	
	/**
	 * Synchronized method for retrieving the front object to display.
	 * @return The front of the data queue.
	 * @throws IllegalStateException if there are no objects to return.
	 */
	protected synchronized Object getNextObject() throws IllegalStateException {
		if (my_data_queue.isEmpty()) {
			throw new IllegalStateException("No more objects to take!");
		}
		return my_data_queue.remove(0);
	}
	
	/**
	 * Abstract displayal method.  This is left to extending classes to implement.
	 */
	protected abstract void display();
}
